import { prisma } from '../../utils/prisma'
import { assertChildOwnership } from '../../utils/guard'
import { getWeekRangeMonday, parseLocalDate } from '../../utils/date'
import { z } from 'zod'

const bodySchema = z.object({
  childId: z.number().int(),
  rewardTemplateId: z.number().int(),
  date: z.string(), // YYYY-MM-DD
  note: z.string().optional()
})

export default eventHandler(async (event) => {
  const body = await readBody(event)
  const parsed = bodySchema.safeParse(body)
  if (!parsed.success) throw createError({ statusCode: 422, statusMessage: 'INVALID_INPUT' })
  const { childId, rewardTemplateId, date, note } = parsed.data
  await assertChildOwnership(event, childId)
  const tpl = await prisma.rewardTemplate.findFirst({ where: { id: rewardTemplateId } })
  if (!tpl) throw createError({ statusCode: 404, statusMessage: 'TEMPLATE_NOT_FOUND' })
  const pointsCost = tpl.costPoints
  const redemptionDate = parseLocalDate(date)

  // optional weekly limit check
  if (tpl.limitPerWeek && tpl.limitPerWeek > 0) {
    const { start, end } = getWeekRangeMonday(date)
    const count = await prisma.redemption.count({
      where: {
        childId,
        rewardTemplateId,
        date: { gte: start, lte: end }
      }
    })
    if (count >= tpl.limitPerWeek) {
      throw createError({ statusCode: 422, statusMessage: 'WEEKLY_LIMIT_REACHED' })
    }
  }

  // balance check based on ledger (earn - spend)
  const { _sum: earnSum } = await prisma.pointsLedger.aggregate({
    where: { childId, kind: 'earn' },
    _sum: { amount: true }
  })
  const { _sum: spendSum } = await prisma.pointsLedger.aggregate({
    where: { childId, kind: 'spend' },
    _sum: { amount: true }
  })
  const { _sum: adjustSum } = await prisma.pointsLedger.aggregate({
    where: { childId, kind: 'adjust' },
    _sum: { amount: true }
  })
  const balance = (earnSum.amount ?? 0) - (spendSum.amount ?? 0) + (adjustSum.amount ?? 0)
  if (balance < pointsCost) throw createError({ statusCode: 422, statusMessage: 'INSUFFICIENT_POINTS' })

  const redemption = await prisma.$transaction(async (tx) => {
    const r = await tx.redemption.create({
      data: { childId, rewardTemplateId, date: redemptionDate, pointsCost, note }
    })
    await tx.pointsLedger.create({
      data: {
        childId,
        kind: 'spend',
        amount: pointsCost,
        sourceType: 'redemption',
        sourceId: r.id,
        occurredAt: redemptionDate  // 使用兑换的日期作为发生时间
      }
    })
    return r
  })

  return { redemption }
})


